package com.iuie.ns.devtools.transfer;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.stereotype.Component;

import com.iuie.ns.devtools.element.DevElement;
import com.iuie.ns.devtools.element.ResultMapDeleteElement;
import com.iuie.ns.devtools.element.ResultMapInsertElement;
import com.iuie.ns.devtools.element.ResultMapMapperElement;
import com.iuie.ns.devtools.element.ResultMapRMapElement;
import com.iuie.ns.devtools.element.ResultMapResultElement;
import com.iuie.ns.devtools.element.ResultMapSelectElement;
import com.iuie.ns.devtools.element.ResultMapUpdateElement;
import com.iuie.ns.devtools.to.DevBodyTO;
import com.iuie.ns.devtools.to.DevHeaderTO;
import com.iuie.ns.devtools.to.ResultMapDevHeaderTO;
import com.iuie.ns.frame.utils.ReflectionUtils;
import com.iuie.ns.frame.utils.StringUtils;
import com.iuie.ns.system.service.code.ISysCodeInfoService;
import com.iuie.ns.system.vo.code.SysCodeInfoVO;

@Component("resultMapTransfer")
public class ResultMapDevTransfer extends BaseDevTransfer {

	@Resource
	private ISysCodeInfoService sysCodeService;
	
	public static final String[] operations = new String[]{"findByCondition", "findById", "deleteById", 
			"addOne", "updateOne", "batchAdd", "batchUpdate", "batchDelete"};
	
	public static final Map<String, Class<?>> operationRelations = new HashMap<String, Class<?>> () {
		private static final long serialVersionUID = 575308852081957450L;
		{
			put("findByCondition", ResultMapSelectElement.class);
			put("findById", ResultMapSelectElement.class);
			put("deleteById", ResultMapDeleteElement.class);
			put("batchDelete", ResultMapDeleteElement.class);
			put("addOne", ResultMapInsertElement.class);
			put("batchAdd", ResultMapInsertElement.class);
			put("updateOne", ResultMapUpdateElement.class);
			put("batchUpdate", ResultMapUpdateElement.class);
		}
	};
	
	@Override
	public String transfer(List<? extends DevBodyTO> list, DevHeaderTO header) {
		ResultMapDevHeaderTO mHeader = (ResultMapDevHeaderTO) header;
		if (StringUtils.isBlank(mHeader.getMybatisVersion())) {
			mHeader.setMybatisVersion("3.0");
		}
		
		final List<DevElement> operationElements = new ArrayList<>();
		for (String operation: operations) {
			try {
				Field field = ReflectionUtils.findField(ResultMapDevHeaderTO.class, operation);
				field.setAccessible(true);
				String value = (String) field.get(mHeader);
				if (StringUtils.equals(value, "1")) {
					Class<?> clazz = operationRelations.get(operation);
					Object obj = clazz.newInstance();
					Field headerField = ReflectionUtils.findField(clazz, "header");
					headerField.setAccessible(true);
					headerField.set(obj, mHeader);
					
					Field operationField = ReflectionUtils.findField(clazz, "operation");
					operationField.setAccessible(true);
					operationField.set(obj, operation);
					
					Field bodysField = ReflectionUtils.findField(clazz, "bodys");
					bodysField.setAccessible(true);
					bodysField.set(obj, list);
					
					Field fieldTypeRelationMapField = ReflectionUtils.findField(clazz, "fieldTypeRelationMap");
					fieldTypeRelationMapField.setAccessible(true);
					fieldTypeRelationMapField.set(obj, getFieldTypeRelationMap());
					
					operationElements.add((DevElement) obj);
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		
		final List<DevElement> resultElements = new ArrayList<>();
		
		if (list != null && list.size() > 0) {
			Iterator<? extends DevBodyTO> it = list.iterator();
			while(it.hasNext()) {
				DevBodyTO body = it.next();
				DevElement resultElement = new ResultMapResultElement(body);
				resultElements.add(resultElement);
			}
		}
		
		final DevElement resultMapElement = new ResultMapRMapElement(mHeader) {

			@Override
			protected List<DevElement> getChildren() {
				return resultElements;
			}
			
		}; // resultMap节点
		
		SysCodeInfoVO mybatisVersionInfo = sysCodeService.findCodeInfoByCodeValueAndCodeType(mHeader.getMybatisVersion(), "mybatisVersion");
		mHeader.setMybatisVersion(mybatisVersionInfo.getCodeInfoName());
		ResultMapMapperElement mapperElement = new ResultMapMapperElement(mHeader) {

			@Override
			protected List<DevElement> getChildren() {
				List<DevElement> allElements = new ArrayList<>();
				allElements.add(resultMapElement);
				allElements.addAll(operationElements);
				return allElements;
			}
			
		};
		return mapperElement.build();
	}

}
